package org.atm.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;

/**
 *
 * @author mbohm
 */
@Entity
@Table(name = "CLIENT")
@NamedQueries({
    @NamedQuery(name = "Client.findAll", query = "SELECT c FROM Client c"),
    @NamedQuery(name = "Client.findAllNew", query = "SELECT c FROM Client c WHERE c.status = 'New'"),
    @NamedQuery(name = "Client.findByClientId", query = "SELECT c FROM Client c WHERE c.clientId = :clientId"),
    @NamedQuery(name = "Client.findByCardNumber", query = "SELECT c FROM Client c WHERE c.ATMCard.cardNumber = :cardNumber"),
    @NamedQuery(name = "Client.findByEmail", query = "SELECT c FROM Client c WHERE c.email = :email")
})
public class Client implements Serializable {

    public static final String APPROVED = "Approved";
    public static final String NEW = "New";
    public static final String REJECTED = "Rejected";
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Basic(optional = false)
    @Column(name = "CLIENT_ID")
    private Integer clientId;
    @Column(name = "FIRST_NAME", nullable = false)
    @NotNull
    private String firstName;
    @Column(name = "LAST_NAME", nullable = false)
    @NotNull
    private String lastName;
    @Column(name = "ADDRESS")
    private String address;
    @Column(name = "PHONE")
    private String phone;
    @Column(name = "EMAIL")
    private String email;
    @Column(name = "BIRTHDATE")
    @Temporal(TemporalType.DATE)
    private Date birthdate;
    @Column(name = "SIN", length = 9)
    private String SIN;
    @Column(name = "STATUS", nullable = false)
    private String status;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "CARD_ID", unique = true, nullable = true, insertable = true, updatable = true)
    private ATMCard ATMCard;
    @OneToMany(mappedBy = "client", fetch= FetchType.EAGER, cascade= CascadeType.ALL)
    private List<Account> accounts;

    public Client() {
    }

    public Client(Integer clientId) {
        this.clientId = clientId;
    }

    @PrePersist
    private void setDefaults() {
        this.status = NEW;
    }

    public Integer getClientId() {
        return clientId;
    }

    public void setClientId(Integer clientId) {
        this.clientId = clientId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String name) {
        this.firstName = name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public String getSIN() {
        return SIN;
    }

    public void setSIN(String SIN) {
        this.SIN = SIN;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (clientId != null ? clientId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Client)) {
            return false;
        }
        Client other = (Client) object;
        if ((this.clientId == null && other.clientId != null) || (this.clientId != null && !this.clientId.equals(other.clientId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return this.firstName;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public void setApproved() {
        this.status = APPROVED;
    }

    public void setRejected() {
        this.status = REJECTED;
    }

    public ATMCard getATMCard() {
        return ATMCard;
    }

    public void setATMCard(ATMCard ATMCard) {
        this.ATMCard = ATMCard;
    }

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    public void addAccount(Account account) {
        if (!getAccounts().contains(account)) {
            getAccounts().add(account);
            if (account.getClient() != null) {
                account.getClient().getAccounts().remove(account);
            }
            account.setClient(this);
        }
    }
}
